<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
  <link rel="stylesheet" href="css/base.css">
  <script src="https://s4.ssl.qhres.com/!928fb688/spritejs.min.js"></script>
  <style>
    html, body {
      width: 100%;
      height: 100%;
      padding: 0;
      margin: 0;
      overflow: hidden;
    }

    #scene-container {
      width: 100%;
      height: 100%;
    }
    #box-rect-demo {
      position: absolute;
      padding: 20px 0 0 20px;
      top: 0;
    }
  </style>
</head>
<body>
  <div id="scene-container"></div>
  <script>
  const {Scene, Sprite} = spritejs
  const scene = new Scene('#scene-container', {
    viewport: ['auto', 'auto'],
    resolution: [1540, 600],
    stickMode: 'width',
  })
  const layer = scene.layer()

  function isPointCollision(circle, x, y) {
    const [r1, r2] = circle.attr('r'),
      width = circle.contentSize[0]

    const bounds = circle.boundingRect,
      [cx, cy] = [bounds[0] + bounds[2] / 2, bounds[1] + bounds[3] / 2]

    const distance = Math.sqrt((x - cx) ** 2 + (y - cy) ** 2)
    return distance >= width / 2 && distance <= width / 2 + r1 - r2
  }

  class Circle extends Sprite {
    pointCollision(evt) {
      if(!super.pointCollision(evt)) {
        return false
      }
      const {offsetX, offsetY} = evt
      return isPointCollision(this, offsetX, offsetY)
    }
  }

  Circle.defineAttributes({
    init(attr) {
      attr.setDefault({
        r: [100, 0],
        color: 'black',
      }, {
        borderRadius() {
          const [r1, r2] = this.r
          return (r1 + r2) / 2
        },
        width() {
          const r2 = this.r[1]
          return 2 * r2
        },
        height() {
          const r2 = this.r[1]
          return 2 * r2
        },
        border() {
          const [r1, r2] = this.r
          return {width: r1 - r2, color: this.color}
        },
      })
    },
    r(attr, val) { // 定义半径属性 [外环，内环]
      attr.clearCache()
      if(!Array.isArray(val)) {
        val = [val, 0]
      }
      attr.set('r', val)
    },
    color(attr, val) {
      attr.clearCache()
      attr.set('color', val)
    },
  })

  const c1 = new Circle()
  c1.attr({
    anchor: [0.5, 0.5],
    pos: [770, 300],
    opacity: 0.5,
    r: 100,
    color: 'red',
  })
  layer.append(c1)

  const c2 = new Circle()
  c2.attr({
    anchor: [0.5, 0.5],
    color: 'rgb(192, 128, 0)',
    r: [100, 50],
    pos: [470, 300],
    opacity: 0.5,
  })
  layer.append(c2)

  const c3 = new Circle()
  c3.attr({
    anchor: [0.5, 0.5],
    color: 'green',
    pos: [1070, 300],
    r: [100, 80],
    opacity: 0.5,
  })
  layer.append(c3)

  ;[c1, c2, c3].forEach((c) => {
    c.on('mouseenter', (evt) => {
      evt.target.attr('opacity', 1)
    })
    c.on('mouseleave', (evt) => {
      evt.target.attr('opacity', 0.5)
    })
  })
  </script>
</body>
</html>
